﻿using HalconDotNet;
using IniReadWrite;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VisionRoc.Tool;

namespace VisionRoc.Core
{

    public class SetCircle
    {
        public string CirclePath;
        public SetCircle(string _Path)
        {
            HOperatorSet.GenEmptyObj(out Spoke);
            HOperatorSet.GenEmptyObj(out Circle);
            HOperatorSet.GenEmptyObj(out Cross);
            //判断文件路径是否存在
            if (!Directory.Exists(_Path))
            {
                Directory.CreateDirectory(_Path);
            }
            CirclePath = _Path + "\\Circle.ini";
            if (File.Exists(CirclePath))
            {
                ReadParameter();
            }
        }

        /// <summary>
        /// 绘制圆时输出Row坐标
        /// </summary>
        public double[] Rows = new double[5];

        /// <summary>
        /// 绘制圆是输出Col坐标
        /// </summary>
        public double[] Cols = new double[5];

        /// <summary>
        /// 拟合输出卡尺区域
        /// </summary>
        HObject Spoke;

        HObject Circle;

        HObject Cross;

        /// <summary>
        /// spoke 输出参数
        /// </summary>
        public HTuple ResultRow = new HTuple();

        /// <summary>
        /// spoke 输出参数
        /// </summary>
        public HTuple ResultCol = new HTuple();

        /// <summary>
        /// 圆中心Row
        /// </summary>
        public HTuple RowCenter = new HTuple();

        /// <summary>
        /// 圆中心Col
        /// </summary>
        public HTuple ColCenter = new HTuple();

        /// <summary>
        /// 圆半径
        /// </summary>
        public HTuple RadiusCircle = new HTuple();

        /// <summary>
        /// 圆起始弧度
        /// </summary>
        public HTuple StartPhi = new HTuple();

        /// <summary>
        /// 圆终点弧度
        /// </summary>
        public HTuple EndPhi = new HTuple();


        public HTuple ArcAngle = new HTuple();

        #region 圆参数

        [Category("1工具参数"), DisplayName("1.卡尺数量"), Description("卡尺数量：\r\n该值的一般区间: 1 ≤ Elements ≤ 100000"), Browsable(true), ReadOnly(false)]
        public int Elements { get; set; } = 30;

        [Category("1工具参数"), DisplayName("2.卡尺高度"), Description("卡尺高度：\r\n建议值: 30, 60, 90, 120"), Browsable(true), ReadOnly(false)]
        public int DetectHeight { get; set; } = 100;

        [Category("1工具参数"), DisplayName("3.卡尺宽度"), Description("卡尺宽度：\r\n建议值: 5, 10, 15, 20, 25, 30"), Browsable(true), ReadOnly(false)]
        public int DetectWidth { get; set; } = 50;

        [Category("1工具参数"), DisplayName("4.滤波因子"), Description("滤波因子：高斯滤波因子\r\n建议值: 0.5, 1, 1.5, 2, 2.5, 3"), Browsable(true), ReadOnly(false)]
        public double Sigma { get; set; } = 1;

        [Category("1工具参数"), DisplayName("5.边缘幅度"), Description("边缘幅度：边缘幅度阈值\r\n建议值: 5, 10, 15, 20, 25, 30, 40"), Browsable(true), ReadOnly(false)]
        public int Threshold { get; set; } = 20;

        [Category("1工具参数"), DisplayName("6.边缘极性"), Description("边缘极性：positive表示由黑到白,\r\nnegative表示由白到黑,\r\nall表示以上两种方向"), Browsable(true), ReadOnly(false)]
        public string Transition { get; set; }
      
        [Category("1工具参数"), DisplayName("7.点选择"), Description("点选择：first表示选择第一点,\r\nlast表示选择最后一点,\r\nmax表示选择边缘幅度最强点"), Browsable(true), ReadOnly(false)]
        public string Select { get; set; }

        [Category("2显示参数"), DisplayName("1.显示点位置"), Description("是否显示点位置"), Browsable(true), ReadOnly(false)]
        public bool DisplayLoction { get; set; } = false;

        [Category("2显示参数"), DisplayName("2.显示线段"), Description("是否显示线段"), Browsable(true), ReadOnly(false)]
        public bool DisplayCircle { get; set; } = false;

        [Category("2显示参数"), DisplayName("3.显示卡尺"), Description("是否显示卡尺"), Browsable(true), ReadOnly(false)]
        public bool DisplayCalib { get; set; } = false;

        [Category("2显示参数"), DisplayName("4.线宽"), Description("线宽"), Browsable(true), ReadOnly(false)]
        public int LineWidth { get; set; } = 3;

        [Category("2显示参数"), DisplayName("5.位置大小"), Description("十字叉大小"), Browsable(true), ReadOnly(false)]
        public int CrossSize { get; set; } = 3;

        [Category("2显示参数"), DisplayName("6.位置颜色"), Description("十字叉颜色"), Browsable(true), ReadOnly(false)]
        public string CrossColor { get; set; } = "red";

        [Category("2显示参数"), DisplayName("7.卡尺颜色"), Description("十字叉颜色"), Browsable(true), ReadOnly(false)]
        public string CalibColor { get; set; } = "blue";

        [Category("2显示参数"), DisplayName("8.圆颜色"), Description("线段颜色"), Browsable(true), ReadOnly(false)]
        public string CircleColor { get; set; } = "green";

        #endregion

        /// <summary>
        /// 圆拟合成功状态
        /// </summary>
        public bool FitCircleState = false;

        /// <summary>
        /// 拟合圆
        /// </summary>
        public void Fit_Circle(HObject Image, HWindow hWindow, HTuple Row, HTuple Col)
        {
            try
            {
                Spoke.Dispose(); ResultRow.Dispose(); ResultCol.Dispose();
                MyHOperatorSet.spoke(Image, out Spoke, Elements, DetectHeight, DetectWidth, Sigma, Threshold, Transition, Select, Row, Col, "outer", out ResultRow, out ResultCol, out _);
                if (ResultRow.TupleLength() > 0 && ResultRow.D > 0)
                {
                    Circle.Dispose(); RowCenter.Dispose();
                    MyHOperatorSet.pts_to_best_circle(out Circle, ResultRow, ResultCol, 3, "circle", out RowCenter, out ColCenter, out RadiusCircle, out StartPhi, out EndPhi, out _, out ArcAngle);
                    if (RowCenter.D > 0)
                    {
                        if (DisplayLoction)
                        {
                            HOperatorSet.SetColor(hWindow, CrossColor);
                            Cross.Dispose();
                            HOperatorSet.GenCrossContourXld(out Cross, ResultRow, ResultCol, CrossSize, 0);
                            HOperatorSet.DispObj(Cross, hWindow);
                        }

                        if (DisplayCircle)
                        {
                            HOperatorSet.SetLineWidth(hWindow, LineWidth);
                            HOperatorSet.SetColor(hWindow, CircleColor);
                            HOperatorSet.DispObj(Circle, hWindow);
                        }
                        if (DisplayCalib)
                        {
                            HOperatorSet.SetLineWidth(hWindow, 1);
                            HOperatorSet.SetColor(hWindow, CalibColor);
                            HOperatorSet.DispObj(Spoke, hWindow);
                        }
                        HOperatorSet.SetColored(hWindow, 12);
                        HOperatorSet.SetLineWidth(hWindow, 2);
                        HOperatorSet.SetColor(hWindow, "red");
                        FitCircleState = true;
                    }
                    else
                    {
                        HOperatorSet.SetColored(hWindow, 12);
                        HOperatorSet.SetLineWidth(hWindow, 2);
                        HOperatorSet.SetColor(hWindow, "red");
                        MyHOperatorSet.DispMeassge(hWindow, "圆拟合失败", "window", "center", "center", 20, "red");
                        FitCircleState = false;
                    }
                }
                else
                {
                    HOperatorSet.SetColored(hWindow, 12);
                    HOperatorSet.SetLineWidth(hWindow, 2);
                    HOperatorSet.SetColor(hWindow, "red");
                    MyHOperatorSet.DispMeassge(hWindow, "Spoke:ResultRow参数错误", "window", "center", "center", 20, "red");
                    FitCircleState = false;
                }
            }
            catch
            {
                HOperatorSet.SetColored(hWindow, 12);
                HOperatorSet.SetLineWidth(hWindow, 2);
                HOperatorSet.SetColor(hWindow, "red");
                MyHOperatorSet.DispMeassge(hWindow, "拟合圆报错", "window", "center", "center", 20, "red");
                FitCircleState = false;
            }

        }


        /// <summary>
        /// 读取参数 
        /// </summary>
        public void ReadParameter()
        {
            Elements = Convert.ToInt32(IniAPI.INIGetStringValue(CirclePath, "CircleParameter", "Elements", "0"));
            DetectHeight = Convert.ToInt32(IniAPI.INIGetStringValue(CirclePath, "CircleParameter", "DetectHeight", "0"));
            DetectWidth = Convert.ToInt32(IniAPI.INIGetStringValue(CirclePath, "CircleParameter", "DetectWidth", "0"));
            Sigma = Convert.ToDouble(IniAPI.INIGetStringValue(CirclePath, "CircleParameter", "Sigma", "0"));
            Threshold = Convert.ToInt32(IniAPI.INIGetStringValue(CirclePath, "CircleParameter", "Threshold", "0"));
            Transition = IniAPI.INIGetStringValue(CirclePath, "CircleParameter", "Transition", "0");
            Select = IniAPI.INIGetStringValue(CirclePath, "CircleParameter", "Select", "0");

            RowCenter = Convert.ToDouble(IniAPI.INIGetStringValue(CirclePath, "FitCircleParameter", "RowCenter", "0"));
            ColCenter = Convert.ToDouble(IniAPI.INIGetStringValue(CirclePath, "FitCircleParameter", "ColCenter", "0"));
            RadiusCircle = Convert.ToDouble(IniAPI.INIGetStringValue(CirclePath, "FitCircleParameter", "RadiusCircle", "0"));
            StartPhi = Convert.ToDouble(IniAPI.INIGetStringValue(CirclePath, "FitCircleParameter", "StartPhi", "0"));
            EndPhi = Convert.ToDouble(IniAPI.INIGetStringValue(CirclePath, "FitCircleParameter", "EndPhi", "0"));
            ArcAngle = Convert.ToDouble(IniAPI.INIGetStringValue(CirclePath, "FitCircleParameter", "ArcAngle", "0"));

            if (Boolean.TryParse(IniAPI.INIGetStringValue(CirclePath, "DisplaySet", "DisplayLoction", "0"), out bool a))
            {
                DisplayLoction = Convert.ToBoolean(IniAPI.INIGetStringValue(CirclePath, "DisplaySet", "DisplayLoction", "0"));
            }
            else
            {
                DisplayLoction = a;
            }

            if (Boolean.TryParse(IniAPI.INIGetStringValue(CirclePath, "DisplaySet", "DisplayCircle", "0"), out bool b))
            {
                DisplayCircle = Convert.ToBoolean(IniAPI.INIGetStringValue(CirclePath, "DisplaySet", "DisplayCircle", "0"));
            }
            else
            {
                DisplayCircle = b;
            }

            if (Boolean.TryParse(IniAPI.INIGetStringValue(CirclePath, "DisplaySet", "DisplayCalib", "0"), out bool c))
            {
                DisplayCalib = Convert.ToBoolean(IniAPI.INIGetStringValue(CirclePath, "DisplaySet", "DisplayCalib", "0"));
            }
            else
            {
                DisplayCalib = c;
            }

            LineWidth = Convert.ToInt32(IniAPI.INIGetStringValue(CirclePath, "DisplaySet", "LineWidth", "0"));
            CircleColor = IniAPI.INIGetStringValue(CirclePath, "DisplaySet", "CircleColor", "0");
            CrossSize = IniAPI.INIGetStringValue(CirclePath, "DisplaySet", "CrossSize", "0").ToInt32();
            CrossColor = IniAPI.INIGetStringValue(CirclePath, "DisplaySet", "CrossColor", "0");
            CalibColor = IniAPI.INIGetStringValue(CirclePath, "DisplaySet", "CalibColor", "0");

            for (int i = 0; i < Rows.Length; i++)
            {
                Rows[i] = Convert.ToDouble(IniAPI.INIGetStringValue(CirclePath, "DrawCircleParameter", "DrawOutRows" + i, "0"));
            }

            for (int i = 0; i < Cols.Length; i++)
            {
                Cols[i] = Convert.ToDouble(IniAPI.INIGetStringValue(CirclePath, "DrawCircleParameter", "DrawOutCols" + i, "0"));
            }
        }

        /// <summary>
        /// 保存参数
        /// </summary>
        public void WriteParameter()
        {
            IniAPI.INIWriteValue(CirclePath, "CircleParameter", "Elements", Elements.ToString());
            IniAPI.INIWriteValue(CirclePath, "CircleParameter", "DetectHeight", DetectHeight.ToString());
            IniAPI.INIWriteValue(CirclePath, "CircleParameter", "DetectWidth", DetectWidth.ToString());
            IniAPI.INIWriteValue(CirclePath, "CircleParameter", "Sigma", Sigma.ToString());
            IniAPI.INIWriteValue(CirclePath, "CircleParameter", "Threshold", Threshold.ToString());
            IniAPI.INIWriteValue(CirclePath, "CircleParameter", "Transition", Transition.ToString());
            IniAPI.INIWriteValue(CirclePath, "CircleParameter", "Select", Select.ToString());

            for (int i = 0; i < Rows.Length; i++)
            {
                IniAPI.INIWriteValue(CirclePath, "DrawCircleParameter", "DrawOutRows" + i, Rows[i].ToString());
            }

            for (int i = 0; i < Cols.Length; i++)
            {
                IniAPI.INIWriteValue(CirclePath, "DrawCircleParameter", "DrawOutCols" + i, Cols[i].ToString());
            }

            IniAPI.INIWriteValue(CirclePath, "FitCircleParameter", "RowCenter", RowCenter.ToString());
            IniAPI.INIWriteValue(CirclePath, "FitCircleParameter", "ColCenter", ColCenter.ToString());
            IniAPI.INIWriteValue(CirclePath, "FitCircleParameter", "RadiusCircle", RadiusCircle.ToString());
            IniAPI.INIWriteValue(CirclePath, "FitCircleParameter", "StartPhi", StartPhi.ToString());
            IniAPI.INIWriteValue(CirclePath, "FitCircleParameter", "EndPhi", EndPhi.ToString());
            IniAPI.INIWriteValue(CirclePath, "FitCircleParameter", "ArcAngle", ArcAngle.ToString());

            IniAPI.INIWriteValue(CirclePath, "DisplaySet", "DisplayLoction", DisplayLoction.ToString());
            IniAPI.INIWriteValue(CirclePath, "DisplaySet", "DisplayCircle", DisplayCircle.ToString());
            IniAPI.INIWriteValue(CirclePath, "DisplaySet", "DisplayCalib", DisplayCalib.ToString());


            IniAPI.INIWriteValue(CirclePath, "DisplaySet", "LineWidth", LineWidth.ToString());
            IniAPI.INIWriteValue(CirclePath, "DisplaySet", "CircleColor", CircleColor.ToString());
            IniAPI.INIWriteValue(CirclePath, "DisplaySet", "CrossSize", CrossSize.ToString());
            IniAPI.INIWriteValue(CirclePath, "DisplaySet", "CrossColor", CrossColor.ToString());
            IniAPI.INIWriteValue(CirclePath, "DisplaySet", "CalibColor", CalibColor.ToString());
        }



    }
}

class GenderItem2 : StringConverter
{
    ////true 启用,false 禁用
    public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
    {
        return true;
    }

    public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
    {
        return new StandardValuesCollection(new string[] { "all", "positive", "negative" }); //编辑下拉框中的items
    }

    //true：禁用文本编辑，false：启用文本编辑
    public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
    {
        return true;
    }
}

class GenderItem_port : StringConverter
{
    ////true 启用,false 禁用
    public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
    {
        return true;
    }
    //max
    // first
    //last
    public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
    {
        return new StandardValuesCollection(new string[] { "max", "first", "last" }); //编辑下拉框中的items
    }
}

